package cn.hpclub.server.util;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * 调用方式】 QueryHelper helper = new QueryHelper(Reply.class, "r")//
 * .addCondition("r.topic=?", topic)// .addOrderProperty("r.postTime", true);
 * 
 * PageBean pageBean = replyService.getPageBean(pageNum, pageSize, helper);
 * 或者添加condition和orderby之后直接调用preparePageBean
 */
/**
 * 
 * 用于生成 select .... 必须select，from前面的 需要查找哪些字段，如果全部就用*表示
 * 
 * 用于生成sqlExceptSelect from ... 必须 哪个表 where 可选 条件1 and 条件2 and ... 条件n brder by
 * 可选 属性1, 属性2, ... 属性n 用于辅助拼接SQL语句
 * 
 * 
 * 支持方法连缀 生成select和sqlExceptSelect语句 $生成参数列表$ $生成查询总记录数的SQL，去除掉OrderBy$
 * 
 * @author 熊诗言 StringBuffer代替String应该还能提升性能
 */
public class QueryHelper{

    public static final boolean ORDER_BY_ASC = true;
    public static final boolean ORDER_BY_DESC = false;
    
    private String       select;                                  // select语句
    private String       fromClause;                              // from子句
    private StringBuffer whereClause   = new StringBuffer("");    // where子句
    private StringBuffer orderByClause = new StringBuffer("");    // order by子句
    private StringBuffer groupByClause = new StringBuffer("");    // group by子句

    private List<Object> parameters    = new ArrayList<Object>(); // 参数列表

    /**
     * 用于一张表的情况，生成From子句
     * 
     * from topic t
     */
    public QueryHelper(String select, String tableName, String alias){
        this.select = select;
        fromClause = new StringBuffer(" from ").append(tableName).append(" ").append(alias).toString();
    }

    /**
     * 用于两张表联合的情况，生成From子句，类似from table1 a,table2 b 然后添加where条件 另外像left join
     * 这种可以写在一个from字句中
     * 
     */
    public QueryHelper(String select, String... froms){
        this.select = select;
        StringBuffer buffer = new StringBuffer(" from ");
        for(String from : froms){
            buffer.append(from).append(",");
        }
        buffer.deleteCharAt(buffer.length() - 1);
        fromClause = buffer.toString();
    }

    public static void main(String[] args){
        QueryHelper helper = new QueryHelper("select a.*,b.*", "table1 a", "table2 b");
        helper.addCondition("a.parentId=b.id");
        // System.out.println(helper.getSelect());
        // System.out.println(helper.getSqlExceptSelect());
    }

    /**
     * 拼接where子句 d.id between ? and ? d.parent=? d.parent is null
     * 
     * @param condition
     * @param params
     */
    public QueryHelper addCondition(String condition, Object... params){
        // 拼接
        if(whereClause.length() == 0){
            whereClause = new StringBuffer(" where ").append(condition);
        } else{
            whereClause.append(" and ").append(condition);
        }

        // 参数
        if(params != null){
            for(Object p : params){
                if(p != null){
                    parameters.add(p);
                }
            }
        }

        return this;
    }

    /**
     * 如果第一个参数为true，则拼接where子句
     * 
     * @param append
     * @param condition
     * @param params
     */
    public QueryHelper addCondition(boolean append, String condition, Object... params){
        if(append){
            addCondition(condition, params);
        }
        return this;
    }

    /**
     * 拼接order by子句
     * 
     * @param propertyName
     *            参与排序的属性名
     * @param asc
     *            true表示升序，false表示降序
     */
    public QueryHelper addOrderProperty(String propertyName, boolean asc){
        if(orderByClause.length() == 0){
            orderByClause = new StringBuffer(" order by ").append(propertyName + (asc ? " asc" : " desc"));
        } else{
            orderByClause.append(", ").append(propertyName + (asc ? " asc" : " desc"));
        }
        return this;
    }

    /**
     * 如果第一个参数为true，则拼接order by子句
     * 
     * @param append
     * @param propertyName
     * @param asc
     */
    public QueryHelper addOrderProperty(boolean append, String propertyName, boolean asc){
        if(append){
            addOrderProperty(propertyName, asc);
        }
        return this;
    }

    public String getSelect(){
        return this.select;
    }

    /**
     * 
     * @Title: addGroupProperty
     * @Description:分组
     * @param propertyName
     * @param asc
     * @return QueryHelper
     */
    public QueryHelper addGroupProperty(String propertyName){
        if(groupByClause.length() == 0){
            groupByClause = new StringBuffer(" group by ").append(propertyName);
        } else{
            groupByClause.append(", ").append(propertyName);
        }
        return this;
    }

    /**
     * 获取生成的用于查询数据列表的sqlExceptSelect语句
     * 
     * @return
     */
    public String getSqlExceptSelect(){
        // 这里面含有一些?，下面来填充
        String sqlExceptSelect = new StringBuffer(fromClause).append(whereClause).append(orderByClause).toString();
        // 填充参数
        if(parameters != null){ // 设置参数
            for(int i = 0; i < parameters.size(); i++){
                // 巧妙利用替换一次之后，后面的?就自动往前移动一位，那么replaceFirst每次替换的就是下一个?
                String param = (parameters.get(i) instanceof Number)?parameters.get(i).toString():"'" + parameters.get(i) + "'";
                sqlExceptSelect = sqlExceptSelect.replaceFirst("\\?", param);
            }
        }
        return sqlExceptSelect;
    }
    
///////////////////////////////////////////////////////由调用者填充参数//////////////////////////////////////////////////////////////////
    /**
     * 拼接where子句 d.id between ? and ? d.parent=? d.parent is null
     * 
     * @param condition
     * @param params
     * @description 不加参数的就需要自己填充参数
     */
    public QueryHelper addCondition(String condition){
        // 拼接
        if(whereClause.length() == 0){
            whereClause = new StringBuffer(" where ").append(condition);
        } else{
            whereClause.append(" and ").append(condition);
        }
        return this;
    }

    /**
     * 如果第一个参数为true，则拼接where子句
     * 
     * @param append
     * @param condition
     * @description 不加参数的就需要自己填充参数
     */
    public QueryHelper addCondition(boolean append, String condition){
        if(append){
            addCondition(condition);
        }
        return this;
    }

    /**
     * 
     * @Title: getSqlExceptSelectByGroup
     * @Description:TODO
     * @return String
     */
    public String getSqlExceptSelectByGroup(){
        // 这里面含有一些?，下面来填充
        String sqlExceptSelect = new StringBuffer(fromClause).append(whereClause).append(groupByClause)
                .append(orderByClause).toString();
        // 填充参数,用JFinal的防注入机制则不需要填充
        // if(parameters != null){ // 设置参数
        // for(int i = 0; i < parameters.size(); i++){
        // // 巧妙利用替换一次之后，后面的?就自动往前移动一位，那么replaceFirst每次替换的就是下一个?
        // sqlExceptSelect = sqlExceptSelect.replaceFirst("\\?", "'" +
        // parameters.get(i) + "'");
        // }
        // }
        return sqlExceptSelect;
    }

    /**
     * 获取生成的用于查询总记录数的SQL语句
     * 
     * @return
     */
    public String getCountQuerySql(){
        return "select count(*) " + fromClause + whereClause;
    }

    /**
     * 获取SQL中的参数值列表
     * 
     * @return
     */
    public List<Object> getParameters(){
        return parameters;
    }
}
